/*
这个文件用来适配不同芯片的寄存器定义
每颗芯片对应一个寄存器头文件
在这里通过宏开关选择
目前只有3172，暂时先直接放在这里
*/

#ifndef __MC31xx_H
#define __MC31xx_H

#include <stdint.h>


/****************************   DEFINE   ****************************/
#ifdef __cplusplus
  #define   __I     volatile                /*!< defines 'read only' permissions      */
#else
  #define   __I     volatile const          /*!< defines 'read only' permissions      */
#endif
#define     __O     volatile                  /*!< defines 'write only' permissions     */
#define     __IO    volatile                  /*!< defines 'read / write' permissions   */

typedef enum { RESET = 0, SET = !RESET } FlagStatus, ITStatus;
typedef enum { DISABLE = 0, ENABLE = !DISABLE } FunctionalState;
#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
typedef enum { ERROR = 0, SUCCESS = !ERROR } ErrorStatus;


//  Set Stack Pointer
#define rothd_set_sp_const(value)               rothd_set_sp_const1(value)
#define rothd_set_sp_const1(value)              asm volatile ("li   sp,"#value"")

#define rothd_set_sp_int(value)                 asm volatile ("mv   %0,sp" : : "r" (value))
#define rothd_get_sp(result)                    asm volatile ("mv   sp,%0" : "=r" (result))

#define NOP()              asm volatile ("nop")

#define THREAD_ID_ADDR                          0x50000000
#define CORE_CNT_ADDR                           0x50000008
#define CORE_INFO1_ADDR                         0x50000400
#define THD_TS_ADDR                             0x50020000
#define CORE_CLK_CFG_ADDR                       0x50050108

#define GET_CORE_CNT(var)                       var=(*(volatile uint32_t*)(CORE_CNT_ADDR))
#define GET_THREAD_ID(var)                      var=(*(volatile uint8_t*)(THREAD_ID_ADDR))

#define CORE_CNT                                (*(volatile uint32_t*)(CORE_CNT_ADDR))

#define THREAD_ID                               (*(volatile uint8_t*)(0x50000000))
#define DATA_RAM_RATIO                          (*(volatile uint8_t*)(0x50010000))

#define THREAD_SPEED                            (*(uint8_t*)(THD_TS_ADDR+THREAD_ID+3))

#define THREAD_FREQCFG_VALUE1       *(uint8_t*)(THD_TS_ADDR+THREAD_ID*8+3) //获得线程分频信息

#define IS_THREAD_ID(THREAD_ID)           ((uint32_t)(THREAD_ID)<64)




/****************************   STRUCT   ****************************/
typedef struct
{
    __IO uint32_t CR;   // [16]EN  [9:8]特权组   [3:0]时钟分频		   外设控制寄存器  w
    uint32_t udf1[15];
    __IO uint32_t OVSR;	 // [31:16]timer占用状态 [15:0]gpcom占用状态 位占用状态寄存器 r
    uint32_t udf2;
    __IO uint32_t IOSR;	 // [31:16]输出状态  	    [15:0]输入状态     位输入输出使能状态寄存器 r
    uint32_t udf3;
    __IO uint32_t DMSR;  //                                        位驱动模式状态寄存器 r
    uint32_t udf4;
    __IO uint32_t PSR;   // [31:16]上拉状态  	    [15:0]下拉状态     位上下拉使能状态寄存器 r
    uint32_t udf5[25];
    __IO uint32_t IEN;	 // [31:16]引脚号，1有效  [15:0]1使能0除能	 位输入使能寄存器 w
    uint32_t udf6[15];
    __IO uint32_t ODR;   // [31:16]引脚号，1有效  [15:0]输出值 	     输出数据寄存器
    uint32_t udf7;
    __IO uint32_t BSR;   // [31:16]引脚号，1有效  [15:0]填0 	       位设置寄存器 w
    uint32_t udf8;
    __IO uint32_t BRR;   // [31:16]引脚号，1有效  [15:0]填0          位清除寄存器 w
    uint32_t udf9;	
    __IO uint32_t BIR;   // [31:16]引脚号，1有效  [15:0]填0		       位翻转寄存器 w
    uint32_t udf10[9];
    __IO uint32_t OEN;   // [31:16]引脚号，1有效  [15：0]1使能0除能   位输出使能寄存器 w
    uint32_t udf11[9];
    __IO uint32_t DMR;   //                                         位驱动模式配置寄存器 W
    uint32_t udf12;
    __IO uint32_t PUEN;  // [31:16]引脚号，1有效  [15:0]1使能0除能	  位上拉使能寄存器 w
    uint32_t udf13;
    __IO uint32_t PDEN;  // [31:16]引脚号，1有效  [15:0]1使能0除能    位下拉使能寄存器  预留，未实装 w
    uint32_t udf14;
    __IO uint32_t FIDR;  // [15:0] 端口输入状态 无触发器 r		        输入数据寄存器 无触发器 确认io输入电平不会变化时，读取实时io状态，若刚好读取时候发生了电平变化，有极小概率死机
    uint32_t udf15[3];
    __IO uint32_t SIDR;  // [15:0] 端口输入状态 有触发器 r		        输入数据寄存器 有触发器 对比实时io状态有两个外设时钟周期的延迟，不过安全
}GPIO_TypeDef;

typedef struct
{
    __IO uint32_t CR;   // [16]EN  [9:8]特权组   [3:0]时钟分频		   外设控制寄存器  w  
    uint32_t udf1;
    __IO uint32_t CR1;  // [8]SPI主从 [7]发送帧格式  [6]接收帧格式 [5:4]SPI模式 [1:0]通信模式选择 控制寄存器1
    uint32_t udf2;
    __IO uint32_t CR2;  // 
    uint32_t udf3;
    __IO uint32_t CR3;  
    uint32_t udf4;
    __IO uint32_t CR4;  
    uint32_t udf5[7];
    __IO uint32_t IOCR; 
    uint32_t udf6; 
    __IO uint32_t ICR;  
    uint32_t udf7[5];
    __IO uint32_t OCR;
    uint32_t udf8[5];
    __IO uint32_t TSR;  
    uint32_t udf9[17];
    __IO uint32_t ITDR3_0;
    uint32_t udf10;
    __IO uint32_t ITDR7_4;
    uint32_t udf11[5];
    __IO uint32_t TDR3_0;
    uint32_t udf12;
    __IO uint32_t TDR7_4;
    uint32_t udf13[5];
    __IO uint32_t ITDR0;
    uint32_t udf14;
    __IO uint32_t ITDR1;
    uint32_t udf15;
    __IO uint32_t ITDR2;
    uint32_t udf16;
    __IO uint32_t ITDR3;
    uint32_t udf17;
    __IO uint32_t ITDR4;
    uint32_t udf18;
    __IO uint32_t ITDR5;
    uint32_t udf19;
    __IO uint32_t ITDR6;
    uint32_t udf20;
    __IO uint32_t ITDR7;
    uint32_t udf21[17];
    __IO uint32_t TDR0;
    uint32_t udf22;
    __IO uint32_t TDR1;
    uint32_t udf23;
    __IO uint32_t TDR2;
    uint32_t udf24;
    __IO uint32_t TDR3;
    uint32_t udf25;
    __IO uint32_t TDR4;
    uint32_t udf26;
    __IO uint32_t TDR5;
    uint32_t udf27;
    __IO uint32_t TDR6;
    uint32_t udf28;
    __IO uint32_t TDR7;
    uint32_t udf29[37];
    __IO uint32_t RWPR;
    uint32_t udf30;
    __IO uint32_t RSR;
    uint32_t udf31[33];
    __IO uint32_t RDR3_0;
    uint32_t udf32;
    __IO uint32_t RDR7_4;
    uint32_t udf33[37];
    __IO uint32_t RDR0;
    uint32_t udf34;
    __IO uint32_t RDR1;
    uint32_t udf35;
    __IO uint32_t RDR2;
    uint32_t udf36;
    __IO uint32_t RDR3;
    uint32_t udf37;
    __IO uint32_t RDR4;
    uint32_t udf38;
    __IO uint32_t RDR5;
    uint32_t udf39;
    __IO uint32_t RDR6;
    uint32_t udf40;
    __IO uint32_t RDR7;
} GPCOM_TypeDef;

/****************************    ADDR    ****************************/
#define GPIOA_BASE                         	0x60100000
#define GPIOB_BASE                         	0x60101000
#define GPIOC_BASE                         	0x60102000
#define GPIOD_BASE                         	0x60103000

#define TIMER0_BASE                        	0x60200000
#define TIMER1_BASE                        	0x60201000
#define TIMER2_BASE                        	0x60202000
#define TIMER3_BASE                        	0x60203000
#define TIMER4_BASE                        	0x60204000
#define TIMER5_BASE                        	0x60205000

#define GPCOM0_BASE                 	    0x60300000
#define GPCOM1_BASE                    		0x60301000
#define GPCOM2_BASE                    		0x60302000
#define GPCOM3_BASE                    		0x60303000
#define GPCOM4_BASE                    		0x60304000
#define GPCOM5_BASE                    		0x60305000
#define GPCOM6_BASE                    		0x60306000
#define GPCOM7_BASE                    		0x60307000
#define GPCOM8_BASE                    		0x60308000
#define GPCOM9_BASE                    		0x60309000
#define GPCOM10_BASE                   		0x6030A000
#define GPCOM11_BASER                   	0x6030B000

/**************************   BIT DEFINE   **************************/
//外设时钟使能
#define INTDEV_RESET                            0x00000
#define INTDEV_RUN                              0x10000
//外设时钟分频
#define INTDEV_CLK_IS_STOP                      0x0000
#define INTDEV_CLK_IS_CORECLK                   0x0001
#define INTDEV_CLK_IS_CORECLK_DIV2              0x0002
#define INTDEV_CLK_IS_CORECLK_DIV4              0x0003
#define INTDEV_CLK_IS_CORECLK_DIV8              0x0004
#define INTDEV_CLK_IS_CORECLK_DIV16             0x0005
#define INTDEV_CLK_IS_CORECLK_DIV32             0x0006
#define INTDEV_CLK_IS_CORECLK_DIV64             0x0007
#define INTDEV_CLK_IS_CORECLK_DIV128            0x0008
#define INTDEV_CLK_IS_CORECLK_DIV256            0x0009
#define INTDEV_CLK_IS_CORECLK_DIV512            0x000A
#define INTDEV_CLK_IS_CORECLK_DIV1024           0x000B
#define INTDEV_CLK_IS_CORECLK_DIV2048           0x000C
#define INTDEV_CLK_IS_CORECLK_DIV4096           0x000D
#define INTDEV_CLK_IS_CORECLK_DIV8192           0x000E
#define INTDEV_CLK_IS_CORECLK_DIV16384          0x000F
//特权组 低特权的线程无法访问高特权的外设 mpu也对特权有要求
#define INTDEV_IS_GROUP0                        0x0000
#define INTDEV_IS_GROUP1                        0x0100
#define INTDEV_IS_GROUP2                        0x0200
#define INTDEV_IS_GROUP3                        0x0300

//gpio
#define GPIO_PIN_0                              0x00010000
#define GPIO_PIN_1                              0x00020000
#define GPIO_PIN_2                              0x00040000
#define GPIO_PIN_3                              0x00080000
#define GPIO_PIN_4                              0x00100000
#define GPIO_PIN_5                              0x00200000
#define GPIO_PIN_6                              0x00400000
#define GPIO_PIN_7                              0x00800000
#define GPIO_PIN_8                              0x01000000
#define GPIO_PIN_9                              0x02000000
#define GPIO_PIN_10                             0x04000000
#define GPIO_PIN_11                             0x08000000
#define GPIO_PIN_12                             0x10000000
#define GPIO_PIN_13                             0x20000000
#define GPIO_PIN_14                             0x40000000
#define GPIO_PIN_15                             0x80000000

#define GPIO_PIN_MASK                           0xFFFF0000
#define GPIO_PIN_ALL                            0xFFFF0000
#define GPIO_PIN_7_0                            0x00FF0000
#define GPIO_PIN_15_8                           0xFF000000

#define GPIO_SET_ENABLE                         0xFFFF
#define GPIO_SET_DISABLE                        0x0000



/****************************   GPIO   ****************************/
#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
#define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)
#define GPIOC               ((GPIO_TypeDef *) GPIOC_BASE)
#define GPIOD               ((GPIO_TypeDef *) GPIOD_BASE)
/****************************   TIMER   ****************************/

/****************************   GPCOM   ****************************/
#define GPCOM0               ((GPCOM_TypeDef *) GPCOM0_BASE)
#define GPCOM1               ((GPCOM_TypeDef *) GPCOM1_BASE)
#define GPCOM2               ((GPCOM_TypeDef *) GPCOM2_BASE)
#define GPCOM3               ((GPCOM_TypeDef *) GPCOM3_BASE)
#define GPCOM4               ((GPCOM_TypeDef *) GPCOM4_BASE)
#define GPCOM5               ((GPCOM_TypeDef *) GPCOM5_BASE)
#define GPCOM6               ((GPCOM_TypeDef *) GPCOM6_BASE)
#define GPCOM7               ((GPCOM_TypeDef *) GPCOM7_BASE)
#define GPCOM8               ((GPCOM_TypeDef *) GPCOM8_BASE)
#define GPCOM9               ((GPCOM_TypeDef *) GPCOM9_BASE)
#define GPCOM10              ((GPCOM_TypeDef *) GPCOM10_BASE)
#define GPCOM11              ((GPCOM_TypeDef *) GPCOM11_BASE)
/****************************    FUN    ****************************/

#endif
